import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rider/app.dart';
import 'package:flutter_rider/event/new_order_event.dart';
import 'package:flutter_rider/kit/sound_kit.dart';
import 'package:flutter_rider/kit/tts_kit.dart';
import 'package:flutter_rider/main/api/app_api.dart';
import 'package:flutter_rider/main/widgets/dialog/alert_dialog.dart';
import 'package:flutter_rider/routers/fluro_navigator.dart';
import 'package:flutter_rider/routers/routers.dart';
import 'package:flutter_rider/utils/device_utils.dart';
import 'package:flutter_rider/utils/extension.dart';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';
import '../api/api.dart';
import '../main.dart';
import '../utils/log.dart';

abstract class MqttKitMessageCallbackInterface {
  onNewOrder(dynamic json);
}

// class MqttKitMessageCallback extends MqttKitMessageCallbackInterface {
//   @override
//   onCancelOrder(json) {
//     SoundKit.instance.playCancelOrder();
//   }
//
//   @override
//   onDispathOrder(json) {
//     SoundKit.instance.playDispatchOrder();
//   }
//
//   @override
//   onNewOrder(json) {
//     SoundKit.instance.playNewOrder();
//   }
// }

class MqttKit {
  MqttKit._privateConstructor();
  static final MqttKit _instance = MqttKit._privateConstructor();

  dynamic _config;
  MqttServerClient? client;
  final List<MqttKitMessageCallbackInterface> _messageCallbacks = [];
  bool _isConnect = false;

  //是否正在接收中
  bool _isReceived = false;

  //去重map
  Set<String> _deduplication = {};

  static MqttKit get instance {
    return _instance;
  }

  connect() {
    //addMessageCallback(MqttKitMessageCallback());
    _loadConfig();
  }

  destroy() {
    client?.disconnect();
    _isConnect = false;
  }

  addMessageCallback(MqttKitMessageCallbackInterface callback) {
    _messageCallbacks.add(callback);
  }

  _initMqtt() {
    if (_isConnect || _config == null) {
      return;
    }
    if (_config["ip"] == null && _config["port"] == null) {
      return;
    }
    _isConnect = true;
    // client = MqttServerClient.withPort(_config["ip"], _config["client_id"],
    //     MqttClientConstants.defaultMqttPort);
    client = MqttServerClient.withPort(
        _config["ip"], _config["client_id"], _config["port"]);
    client?.keepAlivePeriod = 20;
    // //手动连接，不用框架自带的重连
    // client?.autoReconnect = false;
    client?.autoReconnect = true;
    client?.logging(on: true);

    final connMessage = MqttConnectMessage()
        .authenticateAs(_config["username"], _config["password"])
        .withWillTopic('willtopic')
        .withWillMessage('Will message')
        .startClean()
        .withWillQos(MqttQos.atLeastOnce);
    client?.connectionMessage = connMessage;
    client?.onDisconnected = _onDisconnected;
    client?.onConnected = _onConnected;
    // client?.onAutoReconnect = _autoReconnect;

    client?.onSubscribed = (text) {
      Log.i(text);
    };

    client?.pongCallback = () {
      Log.i("pong");
      if (!Api.isLogin()) return;
      //这里处理token过期的问题
      //token_exp 字段
      var user = Api.getUserModel();
      //也可以用状态管理
      int now = DateTime.now().millisecondsSinceEpoch;
      var exp = user.token_exp * 1000;
      if (now > exp) {
        //token 已经过期
        Api.logout();
      }
    };
    client?.connect(_config["username"], _config["password"]);
  }

  _onData(List<MqttReceivedMessage<MqttMessage>> data) {
    Log.i("onData...");
    if (data.length == 1) {
      final recMess = data[0].payload as MqttPublishMessage;
      String pt = const Utf8Decoder().convert(recMess.payload.message);
      try {
        _onMessage(jsonDecode(pt));
      } catch (error, st) {
        Log.i("", error, st);
      }
    }
  }

  _onMessage(dynamic json) async {
    Log.i(json.toString() + "_onMessage");
    var type = json["type"] ?? " ";
    var time = json["timestamp"] ?? "0";
    String text = json["msg"] ?? " ";
    String key = "$type-$time-$text";

    _deduplication.add(key);

    //一条消息消费两次,延迟100毫秒去重之后再播放
    if (!_isReceived) {
      _isReceived = true;
      Future.delayed(const Duration(milliseconds: 100), () {
        Set temp = {};
        for (var element in _deduplication) {
          temp.add(element);
        }
        _deduplication = {};

        for (var element in temp) {
          _actionMessage(element);
        }

        _isReceived = false;
      });
    }
  }

  _actionMessage(String key) {
    var json = key.split("-");

    //release下 iOS 进入后台 MQTT会延迟消费，也就是发送了X条信息，会在进入前台开始一次性接受，需要在消息模块下加入时间戳 10秒内才播放
    var type = json.first;
    if (type == "login_out") {
      Api.logout();
      var context = App.navigatorKey.currentState!.context;
      CustomAlertDialog.showConfirmDialog(context,
          content: "账号已被停用，请联系管理员",
          confirmText: "知道了",
          isShowCancel: false,
          barrierDismissible: false, onConfirm: () {
        NavigatorUtils.push(context, Routes.loginPage, clearStack: true);
      });
      return;
    }

    int msgNow = int.parse(json[1]);
    int now = DateTime.now().millisecondsSinceEpoch;

    int difference = now - msgNow;

    Log.i(difference.toString() + "_onMessage");

    //大于10秒就不发送了
    if (difference > 10000) {
      //消息 已经过期
      return;
    }

    var msg = json.last;

    if (type == "new_waybill") {
      // eventBus.fire(NewOrderEvent()); //市场说不刷新订单了，不然订单找不到
      try {
        String text = msg;
        Log.i("==== using sound kit to play...");
        if (DeviceUtils.instance.getIsTSS()) {
          TTSKit.instance.speak(text);
        } else {
          SoundKit.instance.playNewOrder(0);
        }
      } catch (error, st) {
        Log.i("", error, st);
        SoundKit.instance.playNewOrder(0);
      }
    } else if (type == "cancel_waybill") {
      // eventBus.fire(NewOrderEvent());
      try {
        String text = msg;
        if (DeviceUtils.instance.getIsTSS()) {
          TTSKit.instance.speak(text);
        } else {
          SoundKit.instance.playNewOrder(1);
        }
      } catch (error, st) {
        Log.i("", error, st);
        SoundKit.instance.playNewOrder(1);
      }
    } else if (type == "new_waybill_mission") {
      // eventBus.fire(NewOrderEvent());
      try {
        String text = msg;
        if (DeviceUtils.instance.getIsTSS()) {
          TTSKit.instance.speak(text);
        } else {
          SoundKit.instance.playNewOrder(2);
        }
      } catch (error, st) {
        Log.i("", error, st);
        SoundKit.instance.playNewOrder(2);
      }
    } else if (type == "loading") {
      Log.i("播放装货音频");
      // eventBus.fire(NewOrderEvent());
      try {
        String text = msg;
        if (DeviceUtils.instance.getIsTSS()) {
          TTSKit.instance.speak(text);
        } else {
          SoundKit.instance.playNewOrder(3);
        }
      } catch (error, st) {
        Log.i("", error, st);
        SoundKit.instance.playNewOrder(3);
      }
    } else if (type == "unloading") {
      Log.i("播放卸货音频");
      // eventBus.fire(NewOrderEvent());
      try {
        String text = msg;
        if (DeviceUtils.instance.getIsTSS()) {
          TTSKit.instance.speak(text);
        } else {
          SoundKit.instance.playNewOrder(4);
        }
      } catch (error, st) {
        Log.i("", error, st);
        SoundKit.instance.playNewOrder(4);
      }
    } else if (type == "alarm") {
      Log.i("播放预警音频");
      try {
        String text = msg;
        if (DeviceUtils.instance.getIsTSS()) {
          TTSKit.instance.speak(text);
        } else {
          SoundKit.instance.playNewOrder(5);
        }
      } catch (error, st) {
        Log.i("", error, st);
        SoundKit.instance.playNewOrder(5);
      }
    }
  }

  _loadConfig() {
    _config = Api.getUserInfo()["mqtt"];
    _initMqtt();
  }

  _onConnected() {
    client?.subscribe(_config["subscribe"], MqttQos.atMostOnce);
    client?.updates?.listen(_onData);
    // client?.published?.listen((event) {
    //   Log.i(event.toString());
    // }, onError: (e) {
    //   Log.i(e);
    // }, onDone: () {
    //   Log.i("onDone");
    // });
  }

  //断开连接后的操作
  _onDisconnected() {
    // if (Api.isLogin()) {
    //   //还在登录中
    //   //异常断开 手动重新连接
    //   _isConnect = false;
    //   _loadConfig();
    // }
    Log.i("_onDisconnected");
  }
}
